import * as Cesium from 'cesium';

export interface EntityData {
  id: string | number;
  longitude: number;
  latitude: number;
  name: string;
  [key: string]: any;
}

export interface ClusterOptions {
  pixelRange?: number;
  minimumClusterSize?: number;
  enabled?: boolean;
}

export class CesiumClusterUtil {
  private viewer: Cesium.Viewer;
  private dataSource: Cesium.CustomDataSource;
  private pinBuilder: Cesium.PinBuilder;
  private removeListener: (() => void) | undefined;

  constructor(viewer: Cesium.Viewer) {
    this.viewer = viewer;
    this.pinBuilder = new Cesium.PinBuilder();
    this.initDataSource();
  }

  /**
   * 初始化数据源
   */
  private initDataSource() {
    this.dataSource = new Cesium.CustomDataSource('cluster');
    this.viewer.dataSources.add(this.dataSource);
  }

  /**
   * 初始化聚合配置
   * @param options 聚合配置选项
   */
  public initCluster(options: ClusterOptions = {}) {
    const defaultOptions = {
      pixelRange: 20,
      minimumClusterSize: 5,
      enabled: true
    };

    const clusterOptions = { ...defaultOptions, ...options };

    // 设置聚合参数
    this.dataSource.clustering.enabled = clusterOptions.enabled;
    this.dataSource.clustering.pixelRange = clusterOptions.pixelRange;
    this.dataSource.clustering.minimumClusterSize = clusterOptions.minimumClusterSize;

    // 创建聚合图标
    this.createClusterIcons();
  }

  /**
   * 创建聚合图标
   */
  private createClusterIcons() {
    // 创建不同数量的聚合图标
    const pin100 = this.pinBuilder.fromText('100+', Cesium.Color.BLUE, 48).toDataURL();
    const pin50 = this.pinBuilder.fromText('50+', Cesium.Color.BLUE, 48).toDataURL();
    const pin40 = this.pinBuilder.fromText('40+', Cesium.Color.RED, 48).toDataURL();
    const pin30 = this.pinBuilder.fromText('30+', Cesium.Color.RED, 48).toDataURL();
    const pin20 = this.pinBuilder.fromText('20+', Cesium.Color.RED, 48).toDataURL();
    const pin10 = this.pinBuilder.fromText('10+', Cesium.Color.RED, 48).toDataURL();

    // 创建个位数聚合图标
    const singleDigitPins = new Array(8);
    for (let i = 0; i < singleDigitPins.length; ++i) {
      singleDigitPins[i] = this.pinBuilder.fromText(`${i + 2}`, Cesium.Color.VIOLET, 48).toDataURL();
    }

    // 添加聚合事件监听
    this.removeListener = this.dataSource.clustering.clusterEvent.addEventListener((clusteredEntities, cluster) => {
      cluster.label.show = false;
      cluster.billboard.show = true;
      cluster.billboard.id = cluster.label.id;
      cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;

      // 根据聚合数量设置不同的图标
      if (clusteredEntities.length >= 100) {
        cluster.billboard.image = pin100;
      } else if (clusteredEntities.length >= 50) {
        cluster.billboard.image = pin50;
      } else if (clusteredEntities.length >= 40) {
        cluster.billboard.image = pin40;
      } else if (clusteredEntities.length >= 30) {
        cluster.billboard.image = pin30;
      } else if (clusteredEntities.length >= 20) {
        cluster.billboard.image = pin20;
      } else if (clusteredEntities.length >= 10) {
        cluster.billboard.image = pin10;
      } else {
        cluster.billboard.image = singleDigitPins[clusteredEntities.length - 2];
      }
    });

    // 强制重新聚合
    this.refreshCluster();
  }

  /**
   * 刷新聚合
   */
  private refreshCluster() {
    const pixelRange = this.dataSource.clustering.pixelRange;
    this.dataSource.clustering.pixelRange = 0;
    this.dataSource.clustering.pixelRange = pixelRange;
  }

  /**
   * 更新聚合配置
   * @param options 新的聚合配置
   */
  public updateClusterOptions(options: ClusterOptions) {
    if (this.dataSource.clustering) {
      Object.assign(this.dataSource.clustering, options);
      this.refreshCluster();
    }
  }

  /**
   * 获取数据源
   */
  public getDataSource() {
    return this.dataSource;
  }

  /**
   * 清除所有实体
   */
  public clear() {
    this.dataSource.entities.removeAll();
  }

  /**
   * 销毁实例
   */
  public destroy() {
    if (this.removeListener) {
      this.removeListener();
    }
    if (this.viewer) {
      this.viewer.dataSources.remove(this.dataSource);
    }
  }
}
